home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / 031-040 / amok35 / spellchecker / spellchecker.mod < prev    next >
Text File  |  1993-11-04  |  22KB  |  849 lines

  1. (*********************************************************************
  2.   :Program.    SpellChecker.mod
  3.   :Contents.   Program for checking Textfile for correct writing
  4.   :Author.     Stefan Salewski
  5.   :Copyright.  PD
  6.   :Language.   Modula-2
  7.   :Translator. M2Amiga AMSoft V3.3d
  8.   :History.    V1.0 1.Mar.1990
  9.   :Address.    Stolper Weg 3, D-2160 Stade
  10.   :Imports.    TurboFilesV1.1, Assembler2V1.1 (my own)
  11.   :Imports.    MemSystem (Nicolas Benezan)
  12.   :Imports.    Sound, ARPFileReq, IntuiPointer (Bernd Preussing)
  13. *********************************************************************)
  14.  
  15. MODULE SpellChecker;
  16.   FROM Arts IMPORT Assert,Requester,TermProcedure;
  17.   FROM Assembler2 IMPORT MinInt,MaxInt;
  18.   FROM ARPFileReq IMPORT FileReq;
  19.   FROM Conversions IMPORT ValToStr;
  20.   FROM Exec IMPORT UByte,WaitPort,GetMsg,ReplyMsg;
  21.   FROM Graphics IMPORT jam2,jam1,RectFill,SetDrMd,SetAPen,Text,Move;
  22.   FROM Intuition IMPORT OpenWindow,CloseWindow,NewWindow,WindowPtr,
  23.        IDCMPFlags,IDCMPFlagSet,WindowFlags,WindowFlagSet,Border,StringInfo,
  24.        ScreenFlags,ScreenFlagSet,Gadget,GadgetFlags,GadgetFlagSet,
  25.        ActivationFlags,ActivationFlagSet,IntuiText,boolGadget,strGadget,
  26.        RefreshGadgets,OnGadget,OffGadget,IntuiMessagePtr,GadgetPtr,
  27.        ActivateGadget,AddGList,RemoveGList;
  28.   FROM IntuiPointer IMPORT Busy,Normal;
  29.   FROM Lexi IMPORT SearchString,ExpandLex,SaveLex,LoadLex,ReadWord,InfoSet,
  30.        WordsInLex,InitLex,CleanLex,MinCount,MaxCount,InsertWord,Word,
  31.        MinWordLength,MaxWordLength,ExportLex,IsCap,DeleteWord,Infos;
  32.   FROM Sound IMPORT Sound;
  33.   IMPORT Str;
  34.   FROM Strings IMPORT Insert,Delete;
  35.   FROM SYSTEM IMPORT ADR,BYTE,BITSET,LONGSET,CAST;
  36.   FROM TurboFiles IMPORT FilePtr,Lookup,CloseFile,ReadOnly,TurboResult,
  37.        TurboSetPos,TurboGetPos,SetPosMode,TurboRead,TurboWrite,NewFile,
  38.        ReadWrite,DeleteFile;
  39.  
  40.   CONST
  41.     StartMessage='Attention: Program needs ARP-Library & Device T:';
  42.     LexName='Lexikon';
  43.     TmpName='T:Lex.tmp';
  44.     SaveText='Save File';
  45.     LoadText='Load File';
  46.     CheckText='Check Text';
  47.     ExpandText='Add Words To Lex';
  48.     CleanLexName='T:CleanLex.txt';
  49.     TextName='';
  50.     SaveLexText='Save Lexikon';
  51.     LoadLexText='Load Lexikon';
  52.     ExportText='Export Lexikon';
  53.     WindowTitle='Spellchecker (c) 1990 by Stefan Salewski   ';
  54.     TextLines=3;
  55.     LeftEdge=20;
  56.     TopEdge=20;
  57.     StringLength=80;
  58.     MaxCheckLength=80;
  59.     CopyBufferSize=1024;
  60.     MaxGadgets=10;
  61.     Frame=16;
  62.     YDis=4;
  63.     GadgetHeight=20;
  64.     GadgetWidth=12*8;
  65.     TextHeight=8;
  66.     StrGadgetHeight=9;
  67.     InfoHeight=12;
  68.     TitelHeight=11;
  69.     BL=2;
  70.     WindowWidth=4*GadgetWidth+5*Frame;
  71.     WindowHeight=TextLines*TextHeight+3*GadgetHeight+
  72.                  6*YDis+TitelHeight+Frame DIV 2;
  73.     CharWidth=8;
  74.     LineLength=(WindowWidth-2*Frame) DIV CharWidth;
  75.     BufferSize=(TextLines+1)*LineLength;
  76.     GT0='AddToLex';
  77.     GT0a='Delete It';
  78.     GT1='Ignore';
  79.     GT2='LoadLex';
  80.     GT3='SaveLex';
  81.     GT4='CheckText';
  82.     GT5='Del.Words';
  83.     GT6='Quit';
  84.     GT7='CleanLex';
  85.     GT8='ExpandLex';
  86.     GT9='Export';
  87.     ADD=0;DIT=0;IGN=1;LOA=2;
  88.     SAV=3;CHE=4;DEL=5;QUI=6;
  89.     CLE=7;EPA=8;EPO=9;STR=10;
  90.     Load=FALSE;
  91.     Save=TRUE;
  92.     TFRB=1024;
  93.     TFWB=10240;
  94.  
  95.   TYPE
  96.     InfoText=ARRAY[0..LineLength] OF CHAR;
  97.     String=ARRAY[0..StringLength] OF CHAR;
  98.     FileName=String;
  99.     Line=[1..TextLines];
  100.     Vertex=RECORD
  101.             x,y:INTEGER
  102.           END;
  103.   VAR
  104.     border1,border2,strBorder:Border;
  105.     p:ARRAY[0..45] OF Vertex;
  106.     pStr:ARRAY[0..4] OF Vertex;
  107.     newWindow:NewWindow;
  108.     wPtr:WindowPtr;
  109.     gadget:ARRAY[0..MaxGadgets-1] OF Gadget;
  110.     gText: ARRAY[0..MaxGadgets-1] OF IntuiText;
  111.     stringGadget:Gadget;
  112.     lexName:FileName;
  113.     textName:FileName;
  114.     exName:FileName;
  115.     stringInfo:StringInfo;
  116.     strBuf,undoStrBuf:String;
  117.     minCount,maxCount:UByte;
  118.     lexIsChanged:BOOLEAN;
  119.     integer:INTEGER;
  120.  
  121.   PROCEDURE BeepOK;
  122.   BEGIN
  123.     Sound(6,3,50);
  124.   END BeepOK;
  125.  
  126.   PROCEDURE BeepError;
  127.   BEGIN
  128.     Sound(10,0,500);
  129.   END BeepError;
  130.  
  131.   PROCEDURE Exit;
  132.   BEGIN
  133.     IF wPtr#NIL THEN
  134.       CloseWindow(wPtr);
  135.       wPtr:=NIL;
  136.     END
  137.   END Exit;
  138.  
  139.   PROCEDURE Point(VAR c:CHAR;ok:CHAR);
  140.   BEGIN
  141.     IF (c#ok) AND ((c<=CHAR(31)) OR ((c>=CHAR(128)) AND (c<=CHAR(159)))) THEN
  142.       c:='_'
  143.     END
  144.   END Point;
  145.  
  146.   PROCEDURE ClearTextArea;
  147.   BEGIN
  148.     SetAPen(wPtr^.rPort,1);
  149.     RectFill(wPtr^.rPort,Frame,TitelHeight,
  150.              WindowWidth-1-Frame,TitelHeight+TextLines*(TextHeight+YDis));
  151.   END ClearTextArea;
  152.  
  153.   PROCEDURE DisplayText(VAR text:ARRAY OF CHAR;line:Line;pen:CARDINAL);
  154.   BEGIN
  155.     SetDrMd(wPtr^.rPort,jam1);
  156.     SetAPen(wPtr^.rPort,pen);
  157.     Move(wPtr^.rPort,Frame,TitelHeight-BL+line*(TextHeight+YDis));
  158.     Text(wPtr^.rPort,ADR(text),Str.Length(text));
  159.   END DisplayText;
  160.  
  161.   PROCEDURE Info(errorText:ARRAY OF CHAR);
  162.     VAR
  163.       text:ARRAY[0..WindowWidth DIV CharWidth] OF CHAR;
  164.       num:ARRAY[0..6] OF CHAR;
  165.       l:LONGCARD;
  166.       error:BOOLEAN;
  167.       line:Line;
  168.   BEGIN
  169.     ClearTextArea;
  170.     line:=1;
  171.     IF errorText[0]#0C THEN
  172.       DisplayText(errorText,1,3);
  173.       INC(line)
  174.     END;
  175.     text:='Words in Lexikon: ';
  176.     l:=WordsInLex();
  177.     ValToStr(CAST(LONGINT,l),FALSE,num,10,6,' ',error);
  178.     Str.Concat(text,num);
  179.     DisplayText(text,line,2);
  180.     INC(line);
  181.     text:='MinCount: ';
  182.     l:=minCount;
  183.     ValToStr(CAST(LONGINT,l),FALSE,num,10,3,' ',error);
  184.     Str.Concat(text,num);
  185.     Str.Concat(text,'    MaxCount: ');
  186.     l:=maxCount;
  187.     ValToStr(CAST(LONGINT,l),FALSE,num,10,3,' ',error);
  188.     Str.Concat(text,num);
  189.     DisplayText(text,line,2);
  190.   END Info;
  191.  
  192.   PROCEDURE GadgetsOn(on:BITSET);
  193.   BEGIN
  194.     integer:=RemoveGList(wPtr,ADR(gadget[0]),-1);
  195.     FOR integer:=0 TO MaxGadgets-1 DO
  196.       IF integer IN on THEN
  197.         EXCL(gadget[integer].flags,gadgDisabled);
  198.       ELSE
  199.         INCL(gadget[integer].flags,gadgDisabled);
  200.       END;
  201.     END;
  202.     IF MaxGadgets IN on THEN
  203.       EXCL(stringGadget.flags,gadgDisabled);
  204.     ELSE
  205.       INCL(stringGadget.flags,gadgDisabled);
  206.     END;
  207.     integer:=AddGList(wPtr,ADR(gadget[0]),-1,-1,NIL);
  208.     RefreshGadgets(ADR(gadget[0]),wPtr,NIL);
  209.   END GadgetsOn;
  210.  
  211.   PROCEDURE OpenMainWindow():WindowPtr;
  212.     VAR
  213.       nw:NewWindow;
  214.        w:WindowPtr;
  215.   BEGIN
  216.     WITH nw DO
  217.       leftEdge:=LeftEdge;
  218.       topEdge:=TopEdge;
  219.       width:=WindowWidth;
  220.       height:=WindowHeight;
  221.       detailPen:=-1;
  222.       blockPen:=-1;
  223.       idcmpFlags:=IDCMPFlagSet{gadgetUp,closeWindow};
  224.       flags:=WindowFlagSet{windowDrag,windowDepth,windowClose,activate};
  225.       firstGadget:=NIL;
  226.       checkMark:=NIL;
  227.       title:=ADR(WindowTitle);
  228.       screen:=NIL;
  229.       bitMap:=NIL;
  230.       minWidth:=width;
  231.       minHeight:=height;
  232.       maxWidth:=width;
  233.       maxHeight:=height;
  234.       type:=ScreenFlagSet{wbenchScreen};
  235.     END;
  236.     w:=OpenWindow(nw);
  237.     Assert(w#NIL,ADR("Can't open Window"));
  238.     SetDrMd(w^.rPort,jam2);
  239.     SetAPen(w^.rPort,1);
  240.     RectFill(w^.rPort,4,TitelHeight,WindowWidth-1-4,WindowHeight-1-2);
  241.     integer:=AddGList(w,ADR(gadget[0]),-1,-1,NIL);
  242.     RefreshGadgets(ADR(gadget[0]),w,NIL);
  243.     RETURN w
  244.   END OpenMainWindow;
  245.  
  246.   PROCEDURE InitGadgets;
  247.     VAR
  248.       i,pos:INTEGER;
  249.       x0,x1,y0,y1,dx,dy:INTEGER;
  250.   BEGIN
  251.     x0:=0;
  252.     x1:=GadgetWidth-1-1;
  253.     y0:=0;
  254.     y1:=GadgetHeight-1;
  255.     FOR i:=0 TO 7 DO
  256.       p[0+i*5].x:=x0;
  257.       p[0+i*5].y:=y0;
  258.       p[1+i*5].x:=x1;
  259.       p[1+i*5].y:=y0;
  260.       p[2+i*5].x:=x1;
  261.       p[2+i*5].y:=y1;
  262.       p[3+i*5].x:=x0;
  263.       p[3+i*5].y:=y1;
  264.       p[4+i*5].x:=x0;
  265.       p[4+i*5].y:=y0;
  266.       IF i<2 THEN
  267.         dx:=4;
  268.         dy:=2;
  269.       ELSE
  270.         dx:=1;
  271.         dy:=1;
  272.       END;
  273.       x0:=x0+dx;
  274.       x1:=x1-dx;
  275.       y0:=y0+dy;
  276.       y1:=y1-dy;
  277.     END;
  278.     p[40]:=p[11];
  279.     p[41]:=p[1];
  280.     p[42]:=p[2];
  281.     p[43]:=p[12];
  282.     p[44]:=p[13];
  283.     p[45]:=p[3];
  284.     pStr[0].x:=0;
  285.     pStr[0].y:=0;
  286.     pStr[1].x:=2*GadgetWidth+Frame+1;
  287.     pStr[1].y:=0;
  288.     pStr[2].x:=2*GadgetWidth+Frame+1;
  289.     pStr[2].y:=StrGadgetHeight;
  290.     pStr[3].x:=0;
  291.     pStr[3].y:=StrGadgetHeight;
  292.     pStr[4].x:=0;
  293.     pStr[4].y:=0;
  294.     WITH border1 DO
  295.       leftEdge:=0;
  296.       topEdge:=0;
  297.       frontPen:=2;
  298.       backPen:=0;
  299.       drawMode:=jam2;
  300.       count:=46;
  301.       xy:=ADR(p);
  302.       nextBorder:=ADR(border2);
  303.     END;
  304.     border2:=border1;
  305.     border2.leftEdge:=1;
  306.     border2.nextBorder:=NIL;
  307.     WITH strBorder DO
  308.       leftEdge:=-1;
  309.       topEdge:=-1;
  310.       frontPen:=0;
  311.       backPen:=0;
  312.       drawMode:=jam2;
  313.       count:=5;
  314.       xy:=ADR(pStr);
  315.       nextBorder:=NIL;
  316.     END;
  317.     FOR i:=0 TO MaxGadgets-1 DO
  318.       WITH gadget[i] DO
  319.         IF i<MaxGadgets-1 THEN
  320.           nextGadget:=ADR(gadget[i+1])
  321.         ELSE
  322.           nextGadget:=ADR(stringGadget)
  323.         END;
  324.         IF i>0 THEN
  325.           pos:=i+2
  326.         ELSE
  327.           pos:=i
  328.         END;
  329.         leftEdge:=Frame+(pos MOD 4)*(GadgetWidth+Frame);
  330.         topEdge:=TextLines*TextHeight+TitelHeight+4*YDis+
  331.                  (pos DIV 4)*(GadgetHeight+YDis);
  332.         width:=GadgetWidth;
  333.         height:=GadgetHeight;
  334.         flags:=GadgetFlagSet{};
  335.         activation:=ActivationFlagSet{relVerify};
  336.         gadgetType:=boolGadget;
  337.         gadgetRender:=ADR(border1);
  338.         selectRender:=NIL;
  339.         gadgetText:=ADR(gText[i]);;
  340.         mutualExclude:=LONGSET{};
  341.         specialInfo:=NIL;
  342.         gadgetID:=i;
  343.         userData:=NIL;
  344.       END;
  345.       WITH gText[i] DO
  346.         frontPen:=1;
  347.         backPen:=0;
  348.         drawMode:=jam1;
  349.         leftEdge:=12;
  350.         topEdge:=6;
  351.         iTextFont:=NIL;
  352.         iText:=NIL;
  353.         nextText:=NIL;
  354.       END;
  355.     END;
  356.     gText[0].iText:=ADR(GT0);
  357.     gText[1].iText:=ADR(GT1);
  358.     gText[2].iText:=ADR(GT2);
  359.     gText[3].iText:=ADR(GT3);
  360.     gText[4].iText:=ADR(GT4);
  361.     gText[5].iText:=ADR(GT5);
  362.     gText[6].iText:=ADR(GT6);
  363.     gText[7].iText:=ADR(GT7);
  364.     gText[8].iText:=ADR(GT8);
  365.     gText[9].iText:=ADR(GT9);
  366.     WITH stringInfo DO
  367.       buffer:=ADR(strBuf);
  368.       undoBuffer:=ADR(undoStrBuf);
  369.       bufferPos:=0;
  370.       maxChars:=SIZE(strBuf);
  371.       dispPos:=0;
  372.     END;
  373.     WITH stringGadget DO
  374.       nextGadget:=NIL;
  375.       leftEdge:=Frame+GadgetWidth+Frame;
  376.       topEdge:=TitelHeight+TextLines*TextHeight+5*YDis;
  377.       width:=2*GadgetWidth+Frame;
  378.       height:=StrGadgetHeight;
  379.       flags:=GadgetFlagSet{gadgDisabled};
  380.       activation:=ActivationFlagSet{relVerify};
  381.       gadgetType:=strGadget;
  382.       gadgetRender:=ADR(strBorder);
  383.       selectRender:=NIL;
  384.       gadgetText:=NIL;
  385.       mutualExclude:=LONGSET{};
  386.       specialInfo:=ADR(stringInfo);
  387.       gadgetID:=MaxGadgets;
  388.       userData:=NIL;
  389.     END;
  390.     INCL(gadget[0].flags,gadgDisabled);
  391.     INCL(gadget[1].flags,gadgDisabled);
  392.   END InitGadgets;
  393.  
  394.   PROCEDURE LoadLexikon;
  395.   BEGIN
  396.     IF FileReq(lexName,NIL,LoadLexText,Load) THEN
  397.       Busy(wPtr);
  398.       IF LoadLex(lexName) THEN
  399.         lexIsChanged:=FALSE;
  400.         minCount:=MinCount();
  401.         maxCount:=MaxCount();
  402.         Info('Lexikon Loaded!');
  403.         BeepOK
  404.       ELSE
  405.         Info('Error while loading Lexikon!');
  406.         BeepError;
  407.       END;
  408.       Normal(wPtr);
  409.     END;
  410.   END LoadLexikon;
  411.  
  412.   PROCEDURE SaveLexikon;
  413.   BEGIN
  414.     IF FileReq(lexName,NIL,SaveLexText,Save) THEN
  415.       Busy(wPtr);
  416.       IF SaveLex(lexName) THEN
  417.         lexIsChanged:=FALSE;
  418.         Info('Lexikon saved!');
  419.         BeepOK;
  420.       ELSE
  421.         Info('Error while saving Lexikon!');
  422.         BeepError;
  423.       END;
  424.       Normal(wPtr);
  425.     END;
  426.   END SaveLexikon;
  427.  
  428.   PROCEDURE Export;
  429.   BEGIN
  430.     IF FileReq(exName,NIL,ExportText,Save) THEN
  431.       Busy(wPtr);
  432.       IF ExportLex(exName) THEN
  433.         Info('Lexikon exported!');
  434.         BeepOK;
  435.       ELSE
  436.         Info('Error while exporting Lexikon!');
  437.         BeepError;
  438.       END;
  439.       Normal(wPtr);
  440.     END;
  441.   END Export;
  442.  
  443.   PROCEDURE ExamineText;
  444.     VAR
  445.       tmpName:FileName;
  446.       infoText:InfoText;
  447.       buffer:ARRAY[0..BufferSize] OF CHAR;
  448.       sourcePtr,destPtr:FilePtr;
  449.       pos:CARDINAL;
  450.       len:LONGINT;
  451.       word,copy:ARRAY[0..MaxCheckLength] OF CHAR;
  452.       exit:BOOLEAN;
  453.       info:InfoSet;
  454.       isCap,error:BOOLEAN;
  455.       sourceOpen,tmpOpen:BOOLEAN;
  456.  
  457.     PROCEDURE DisplayError;
  458.       VAR
  459.         line:Line;
  460.         cp,newPos,oldPos,errorPos:LONGINT;
  461.         actual,hhh,skip:LONGINT;
  462.     BEGIN
  463.       ClearTextArea;
  464.       cp:=TurboGetPos(sourcePtr);
  465.       skip:=MinInt(len+LineLength,cp);
  466.       IF TurboSetPos(sourcePtr,-skip,current) THEN END;
  467.       TurboRead(sourcePtr,ADR(buffer),BufferSize-1,actual);
  468.       buffer[actual]:=0C;
  469.       errorPos:=skip-len;
  470.       hhh:=Str.FirstPos(buffer,0,'.');
  471.       IF (hhh<0) OR (hhh>errorPos) THEN
  472.         hhh:=Str.FirstPos(buffer,0,' ');
  473.         IF (hhh<0) OR (hhh>errorPos) THEN
  474.           hhh:=0
  475.         END;
  476.       END;
  477.       FOR newPos:=0 TO actual-1 DO
  478.         Point(buffer[newPos],' ')
  479.       END;
  480.       SetAPen(wPtr^.rPort,2);
  481.       SetDrMd(wPtr^.rPort,jam1);
  482.       FOR line:=1 TO TextLines DO
  483.         Move(wPtr^.rPort,Frame,TitelHeight-BL+line*(TextHeight+YDis));
  484.         newPos:=hhh;
  485.         REPEAT
  486.           oldPos:=newPos;
  487.           newPos:=Str.FirstPos(buffer,oldPos+1,' ');
  488.         UNTIL (newPos>hhh+LineLength) OR (newPos=-1);
  489.         IF oldPos=hhh THEN oldPos:=hhh+LineLength END;
  490.         IF oldPos>actual THEN
  491.           oldPos:=actual
  492.         END;
  493.         WHILE hhh<oldPos DO
  494.           IF hhh=errorPos THEN
  495.             SetAPen(wPtr^.rPort,3)
  496.           ELSIF
  497.             hhh=errorPos+len THEN
  498.             SetAPen(wPtr^.rPort,2)
  499.           END;
  500.           Text(wPtr^.rPort,ADR(buffer[hhh]),1);
  501.           INC(hhh);
  502.         END;
  503.       END;
  504.       IF sourcePtr^.res=endOfFile THEN
  505.         sourcePtr^.res:=done
  506.       END;
  507.       IF TurboSetPos(sourcePtr,cp,beginning) THEN END;
  508.     END DisplayError;
  509.  
  510.     PROCEDURE Ignore;
  511.     BEGIN
  512.     END Ignore;
  513.  
  514.     PROCEDURE Add;
  515.       VAR
  516.         w:Word;
  517.         pos:CARDINAL;
  518.         l:INTEGER;
  519.     BEGIN
  520.       (*
  521.       LOOP
  522.         l:=Str.FirstPos(strBuf,0,'-');
  523.         IF l=-1 THEN
  524.           EXIT
  525.         ELSE
  526.           Delete(strBuf,l,0)
  527.         END;
  528.       END;
  529.       *)
  530.       IF NOT SearchString(strBuf,pos,1) THEN
  531.         IF (pos#0) AND (Str.Length(strBuf)<=MaxWordLength) THEN
  532.           Str.Copy(w,strBuf);
  533.           InsertWord(w,pos,2);
  534.           lexIsChanged:=TRUE;
  535.         END;
  536.       END;
  537.     END Add;
  538.  
  539.   PROCEDURE AddOrIgnore;
  540.   VAR
  541.     i:INTEGER;
  542.     intuiMessagePtr:IntuiMessagePtr;
  543.     class:IDCMPFlagSet;
  544.     code:CARDINAL;
  545.     gadgetPtr:GadgetPtr;
  546.   BEGIN
  547.     Str.Copy(strBuf,word);
  548.     RefreshGadgets(ADR(stringGadget),wPtr,NIL);
  549.     IF ActivateGadget(ADR(stringGadget),wPtr,NIL) THEN END;
  550.     WaitPort(wPtr^.userPort);
  551.     intuiMessagePtr:=GetMsg(wPtr^.userPort);
  552.     class:=intuiMessagePtr^.class;
  553.     code:= intuiMessagePtr^.code;
  554.     IF TurboSetPos(destPtr,-LONGINT(len),current) THEN END;
  555.     TurboWrite(destPtr,ADR(strBuf),Str.Length(strBuf));
  556.     IF gadgetUp IN class THEN
  557.       gadgetPtr:=intuiMessagePtr^.iAddress;
  558.       i:=gadgetPtr^.gadgetID;
  559.       ReplyMsg(intuiMessagePtr);
  560.       CASE i OF
  561.         |ADD:Add;
  562.         |IGN:(*Ignore;*)
  563.         |QUI:exit:=TRUE;
  564.         |STR:(*Ignore;*)
  565.       ELSE
  566.         HALT;
  567.       END;
  568.     ELSE
  569.       exit:=TRUE;
  570.       ReplyMsg(intuiMessagePtr);
  571.     END;
  572.   END AddOrIgnore;
  573.  
  574.   PROCEDURE CopyFiles(VAR sourceName,destName:ARRAY OF CHAR):BOOLEAN;
  575.     VAR
  576.       buf:ARRAY[0..CopyBufferSize-1] OF BYTE;
  577.       act:LONGINT;
  578.       source,dest:FilePtr;
  579.       ok:BOOLEAN;
  580.   BEGIN
  581.     ok:=FALSE;
  582.     IF Lookup(source,sourceName,TFRB,ReadOnly)=done THEN
  583.       IF Lookup(dest,destName,TFWB,NewFile)=done THEN
  584.         WHILE (source^.res=done) DO
  585.           TurboRead(source,ADR(buf),SIZE(buf),act);
  586.           TurboWrite(dest, ADR(buf),act)
  587.         END;
  588.         ok:=(source^.res=endOfFile) AND (dest^.res=done);
  589.         CloseFile(dest);
  590.       END;
  591.       CloseFile(source);
  592.     END;
  593.     RETURN ok;
  594.   END CopyFiles;
  595.  
  596.   BEGIN
  597.     tmpName:=TmpName;
  598.     exit:=FALSE;
  599.     IF FileReq(textName,NIL,CheckText,Save) THEN
  600.       IF Lookup(sourcePtr,textName,TFRB,ReadOnly)#done THEN
  601.         Info("Can't open Textfile!");
  602.         BeepError;
  603.         RETURN
  604.       END;
  605.       IF Lookup(destPtr,tmpName,TFWB,NewFile)#done THEN
  606.         CloseFile(sourcePtr);
  607.         Info("Can't open Tmp-File!");
  608.         BeepError;
  609.         RETURN
  610.       END;
  611.       GadgetsOn({ADD,IGN,QUI,STR});
  612.       ClearTextArea;
  613.       infoText:='Checking Text for WriteErrors';
  614.       DisplayText(infoText,1,3);
  615.       infoText:='If You select Quit or Close-Gadget,';
  616.       DisplayText(infoText,2,3);
  617.       infoText:='then the file will be NOT changed!';
  618.       DisplayText(infoText,3,3);
  619.       REPEAT
  620.         ReadWord(sourcePtr,destPtr,word,info,MinWordLength,MaxCheckLength);
  621.         IF word[0]#0C THEN
  622.           isCap:=IsCap(word[0]);
  623.           copy:=word;
  624.           error:=(cap IN info) AND NOT isCap;
  625.           IF NOT error THEN
  626.             error:=NOT SearchString(copy,pos,1);
  627.             IF error AND (cap IN info) (*AND isCap*) THEN
  628.               copy:=word;
  629.               INC(CAST(UByte,copy[0]),32);
  630.               error:=NOT SearchString(copy,pos,1);
  631.             END
  632.           END;
  633.           IF error THEN
  634.             len:=Str.Length(word);
  635.             DisplayError;
  636.             BeepOK;
  637.             AddOrIgnore;
  638.           END;
  639.         END;
  640.       UNTIL (sourcePtr^.res#done) OR exit;
  641.       CloseFile(sourcePtr);
  642.       CloseFile(destPtr);
  643.       minCount:=MinCount();
  644.       maxCount:=MaxCount();
  645.       IF NOT exit THEN
  646.         IF CopyFiles(tmpName,textName) THEN
  647.           Info('All errors corrected!');
  648.           BeepOK;
  649.         ELSE
  650.           Info('Read-Write-Error');
  651.           BeepError;
  652.         END;
  653.       ELSE
  654.         Info('Abort: File is unchanged!');
  655.         BeepOK;
  656.       END;
  657.       GadgetsOn({LOA..EPO});
  658.       IF DeleteFile(tmpName) THEN END;
  659.     END;
  660.   END ExamineText;
  661.  
  662.   PROCEDURE DelWords;
  663.   VAR
  664.     w:Word;
  665.     i:INTEGER;
  666.     intuiMessagePtr:IntuiMessagePtr;
  667.     class:IDCMPFlagSet;
  668.     code:CARDINAL;
  669.     gadgetPtr:GadgetPtr;
  670.     infoText:InfoText;
  671.   BEGIN
  672.     infoText:='Type word to delete into StringGadget';
  673.     ClearTextArea;
  674.     DisplayText(infoText,1,3);
  675.     infoText:='Click DeleteIt or press RETURN to delete';
  676.     DisplayText(infoText,2,3);
  677.     infoText:='Click Close- or Quit-Gadget to exit';
  678.     DisplayText(infoText,3,3);
  679.     gText[0].iText:=ADR(GT0a);
  680.     GadgetsOn({DIT,IGN,QUI,STR});
  681.     LOOP
  682.       IF ActivateGadget(ADR(stringGadget),wPtr,NIL) THEN END;
  683.       WaitPort(wPtr^.userPort);
  684.       intuiMessagePtr:=GetMsg(wPtr^.userPort);
  685.       class:=intuiMessagePtr^.class;
  686.       code:= intuiMessagePtr^.code;
  687.       IF gadgetUp IN class THEN
  688.         gadgetPtr:=intuiMessagePtr^.iAddress;
  689.         i:=gadgetPtr^.gadgetID;
  690.         ReplyMsg(intuiMessagePtr);
  691.         CASE i OF
  692.           |ADD,STR:
  693.             IF Str.Length(strBuf)<=MaxWordLength THEN
  694.               Str.Copy(w,strBuf);
  695.               IF DeleteWord(w) THEN
  696.                 lexIsChanged:=TRUE;
  697.                 Info('Wort deleted!');
  698.                 BeepOK;
  699.               ELSE
  700.                 Info('Word NOT found!');
  701.                 BeepError;
  702.               END;
  703.             ELSE
  704.               Info('Word NOT found!');
  705.               BeepError;
  706.             END;
  707.           |IGN:
  708.             Info('Word not Deleted!');
  709.             BeepOK;
  710.           |QUI:EXIT;
  711.         ELSE
  712.           HALT;
  713.         END;
  714.       ELSE
  715.         ReplyMsg(intuiMessagePtr);
  716.         EXIT
  717.       END;
  718.     END;
  719.     minCount:=MinCount();
  720.     maxCount:=MaxCount();
  721.     Info('');
  722.     BeepOK;
  723.     gText[0].iText:=ADR(GT0);
  724.     GadgetsOn({LOA..EPO});
  725.   END DelWords;
  726.  
  727.   PROCEDURE Clean;
  728.     VAR
  729.       oldMinCount:CARDINAL;
  730.       fileName:FileName;
  731.   BEGIN
  732.     Busy(wPtr);
  733.     lexIsChanged:=TRUE;
  734.     fileName:=CleanLexName;
  735.     oldMinCount:=CleanLex(fileName);
  736.     minCount:=MinCount();
  737.     maxCount:=MaxCount();
  738.     fileName:='Lexikon cleaned! (to ';
  739.     Str.Concat(fileName,CleanLexName);
  740.     Str.Concat(fileName,')');
  741.     Info(fileName);
  742.     Normal(wPtr);
  743.     BeepOK;
  744.   END Clean;
  745.  
  746.   (*
  747.   PROCEDURE Words0;
  748.   BEGIN
  749.     InitLex;
  750.     Info('Lexikon initialized!');
  751.   END Words0;
  752.   *)
  753.  
  754.   PROCEDURE Expand;
  755.     VAR
  756.       infoText:InfoText;
  757.   BEGIN
  758.     (*textName:=TextName;*)
  759.     IF FileReq(textName,NIL,ExpandText,Load) THEN
  760.       ClearTextArea;
  761.       infoText:='Expanding Lexikon';
  762.       DisplayText(infoText,1,2);
  763.       infoText:='Please have some patience';
  764.       DisplayText(infoText,2,2);
  765.       GadgetsOn({});
  766.       Busy(wPtr);
  767.       IF ExpandLex(textName) THEN
  768.         lexIsChanged:=TRUE;
  769.         minCount:=MinCount();
  770.         maxCount:=MaxCount();
  771.         Info('Lexikon expanded!');
  772.         BeepOK;
  773.       ELSE
  774.         Info("Can't expand Lexikon!");
  775.         BeepError;
  776.       END;
  777.       Normal(wPtr);
  778.       GadgetsOn({LOA..EPO});
  779.     END
  780.   END Expand;
  781.  
  782.   PROCEDURE ReallyExit():BOOLEAN;
  783.   BEGIN
  784.     RETURN NOT lexIsChanged OR
  785.                Requester(ADR('Lexikon has been changed !'),
  786.                          ADR('Will You go back to save it ?'),
  787.                          ADR('Exit'),
  788.                          ADR('Go Back'))
  789.   END ReallyExit;
  790.  
  791.   PROCEDURE GetMessage;
  792.     VAR
  793.       i:INTEGER;
  794.       intuiMessagePtr:IntuiMessagePtr;
  795.       class:IDCMPFlagSet;
  796.       code:CARDINAL;
  797.       gadgetPtr:GadgetPtr;
  798.   BEGIN
  799.     LOOP
  800.       WaitPort(wPtr^.userPort);
  801.       intuiMessagePtr:=GetMsg(wPtr^.userPort);
  802.       class:=intuiMessagePtr^.class;
  803.       code:= intuiMessagePtr^.code;
  804.       IF gadgetUp IN class THEN
  805.         gadgetPtr:=intuiMessagePtr^.iAddress;
  806.         i:=gadgetPtr^.gadgetID;
  807.         ReplyMsg(intuiMessagePtr);
  808.         CASE i OF
  809.           (*|ADD:AddToLex;
  810.           |IGN:Ignore;*)
  811.           |LOA:LoadLexikon;
  812.           |SAV:SaveLexikon;
  813.           |CHE:ExamineText;
  814.           |DEL:DelWords;
  815.           |QUI:IF ReallyExit() THEN EXIT END;
  816.           |CLE:Clean;
  817.           |EPA:Expand;
  818.           |EPO:Export;
  819.           (*|STR:AddToLex;*)
  820.         ELSE
  821.           HALT
  822.         END;
  823.       ELSE
  824.         ReplyMsg(intuiMessagePtr);
  825.         IF ReallyExit() THEN EXIT END;
  826.       END;
  827.       REPEAT
  828.         intuiMessagePtr:=GetMsg(wPtr^.userPort);
  829.       UNTIL intuiMessagePtr=NIL;
  830.     END;
  831.   END GetMessage;
  832.  
  833. BEGIN
  834.   lexIsChanged:=FALSE;
  835.   minCount:=0;
  836.   maxCount:=0;
  837.   lexName:=LexName;
  838.   textName:=TextName;
  839.   exName:="";
  840.   wPtr:=NIL;
  841.   TermProcedure(Exit);
  842.   InitGadgets;
  843.   wPtr:=OpenMainWindow();
  844.   Info(StartMessage);
  845.   GadgetsOn({LOA..EPO});
  846.   GetMessage;
  847. END SpellChecker.
  848.  
  849.